package com.itcoon.cloud.framework.loadbalancer.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.itcoon.cloud.framework.loadbalancer.config.properties.LoadBalancerProperties;
import com.itcoon.cloud.framework.loadbalancer.core.GrayLoadBalancer;
import com.itcoon.cloud.framework.loadbalancer.core.NacosLocalFirstLoadBalancer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.*;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

/**
 * nacos 负载均衡同IP 同区域有限
 */

public class LoadBalancerInstanceBeanConfig {

    private static final Logger log = LoggerFactory.getLogger(LoadBalancerInstanceBeanConfig.class);

    private final LoadBalancerProperties properties;

    public LoadBalancerInstanceBeanConfig(LoadBalancerProperties properties) {
        this.properties = properties;
    }

    @Bean
    public ReactorLoadBalancer<ServiceInstance> nacosLocalFirstLoadBalancer(Environment environment,
                                                                  LoadBalancerClientFactory loadBalancerClientFactory,
                                                                  NacosDiscoveryProperties nacosDiscoveryProperties){

        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        if(log.isDebugEnabled()) {
            log.debug("Use load balancer for {} service", name);
        }
        ObjectProvider<ServiceInstanceListSupplier> lazyProvider = loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class);
        ReactorServiceInstanceLoadBalancer instanceLoadBalancer = null;
        switch (properties.getBalancerEnum()){
            case RANDOM:
                 instanceLoadBalancer = new RandomLoadBalancer(lazyProvider, name);
                 break;
            case LOCAL_FIRST:
                instanceLoadBalancer = new NacosLocalFirstLoadBalancer(lazyProvider, name, nacosDiscoveryProperties);
                break;
            case GRAY:
                instanceLoadBalancer = new GrayLoadBalancer(lazyProvider, name);
                break;
            default:
                instanceLoadBalancer = new RoundRobinLoadBalancer(lazyProvider, name);
        }
        return instanceLoadBalancer;
    }
}

